package com.xvyy.tingshu.search.thread;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ClassName: ExpireThread
 * Package: com.xvyy.tingshu.search.thread
 *
 * @Description: 续期线程，保证锁的续期
 * @Author: xvyy
 * @Create: 2025/2/6 - 22:39
 * @Version: v1.0
 */
@Slf4j
public class ExpireThread {
    private volatile boolean isStop = false;

    private StringRedisTemplate stringRedisTemplate;

    public ExpireThread(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    HashMap<String, Thread> stringThreadHashMap = new HashMap<>();
    ReentrantLock reentrantLock = new ReentrantLock();

    /**
     * 续期线程
     */
    public void expire(String lockKey, Long interval, Long ttl) {
        // 加锁，保证单例执行，防止重复创建续期线程
        reentrantLock.lock();
        Thread expireThread = stringThreadHashMap.get("expire");
        if (expireThread == null) {
            try {
                // 方式一 中断机制interrupt  任务没了，线程不会在
/*        Thread expireThread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 启动一个续期线程
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        Thread.sleep(10);//续期间隔
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    stringRedisTemplate.expire(cacheKey, 60, TimeUnit.SECONDS);
                }
            }
        });*/
                // 方式二 变量的可见性volatile  任务没了，线程还在
                expireThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // 启动一个续期线程
                        while (!isStop) {
                            try {
                                Thread.sleep(interval);//续期间隔
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                            log.info("{}开始续期", Thread.currentThread().getName());
                            stringRedisTemplate.expire(lockKey, ttl, TimeUnit.SECONDS);
                        }
                    }
                });
                stringThreadHashMap.put("expire", expireThread);
                //设置为守护线程，守护线程会随着主线程的结束而结束
                expireThread.setDaemon(true);
                expireThread.start();
                expireThread.setName("expire-lock-thread");
            } finally {
                reentrantLock.unlock();
            }
        } else {
            expireThread.run();
        }
    }

    /**
     * 停止续期线程
     */
    public void expireStop() {
        // 不管有没有异常，都会中断
//        expireThread.interrupt();// 续期线程中断
        isStop = true;//volatile关键字，保证可见性
    }
}
